﻿using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Collections.Generic;
using System.Drawing.Imaging;

namespace ImageProcessor.Shared.Processing
{

    /// <summary>
    /// Используеться для обработки изображений
    /// </summary>
    public class Filter
    {
        /// <summary>
        /// Инициализация
        /// </summary>
        public Filter()
        {
            _FilterMatrix = new int[3, 3];
        }
        /// <summary>
        /// Инициализация
        /// </summary>
        public Filter(int Width, int Height)
        {
            _FilterMatrix = new int[Width, Height];
            this.Width = Width;
            this.Height = Height;
        }
        private int[,] _FilterMatrix = null;
        private int _Width = 3;
        private int _Height = 3;
        private int _Offset = 0;
        /// <summary>
        /// Текущая матрица
        /// </summary>
        public int[,] FilterMatrix
        {
            get { return _FilterMatrix; }
            set { _FilterMatrix = value; }
        }
        /// <summary>
        /// Ширина матрицы
        /// </summary>
        public int Width
        {
            get { return _Width; }
            set { _Width = value; }
        }
        /// <summary>
        /// Высота матрицы
        /// </summary>
        public int Height
        {
            get { return _Height; }
            set { _Height = value; }
        }
        /// <summary>
        /// Сдвиг цветовых значений
        /// </summary>
        public int Offset
        {
            get { return _Offset; }
            set { _Offset = value; }
        }
        /// <summary>
        /// Возвращает изображение с применением фильтра
        /// </summary>
        public Bitmap ApplyFilter(Bitmap Input)
        {
            Bitmap TempBitmap = Input;
            Bitmap NewBitmap = new Bitmap(TempBitmap.Width, TempBitmap.Height);
            Graphics NewGraphics = Graphics.FromImage(NewBitmap);
            NewGraphics.DrawImage(TempBitmap, new Rectangle(0, 0, TempBitmap.Width, TempBitmap.Height), new Rectangle(0, 0, TempBitmap.Width, TempBitmap.Height), GraphicsUnit.Pixel);
            NewGraphics.Dispose();
            for (int x = 0; x < Input.Width; ++x)
            {
                for (int y = 0; y < Input.Height; ++y)
                {
                    int RValue = 0;
                    int GValue = 0;
                    int BValue = 0;
                    int Weight = 0;
                    int XCurrent = -Width / 2;
                    for (int x2 = 0; x2 < Width; ++x2)
                    {
                        if (XCurrent + x < Input.Width && XCurrent + x >= 0)
                        {
                            int YCurrent = -Height / 2;
                            for (int y2 = 0; y2 < Height; ++y2)
                            {
                                if (YCurrent + y < Input.Height && YCurrent + y >= 0)
                                {
                                    RValue += FilterMatrix[x2, y2] * TempBitmap.GetPixel(XCurrent + x, YCurrent + y).R;
                                    GValue += FilterMatrix[x2, y2] * TempBitmap.GetPixel(XCurrent + x, YCurrent + y).G;
                                    BValue += FilterMatrix[x2, y2] * TempBitmap.GetPixel(XCurrent + x, YCurrent + y).B;
                                    Weight += FilterMatrix[x2, y2];
                                }
                                ++YCurrent;
                            }
                        }
                        ++XCurrent;
                    }
                    Color MeanPixel = TempBitmap.GetPixel(x, y);
                    if (Weight == 0)
                        Weight = 1;
                    if (Weight > 0)
                    {
                        RValue = (RValue / Weight) + Offset;
                        if (RValue < 0)
                            RValue = 0;
                        else if (RValue > 255)
                            RValue = 255;
                        GValue = (GValue / Weight) + Offset;
                        if (GValue < 0)
                            GValue = 0;
                        else if (GValue > 255)
                            GValue = 255;
                        BValue = (BValue / Weight) + Offset;
                        if (BValue < 0)
                            BValue = 0;
                        else if (BValue > 255)
                            BValue = 255;
                        MeanPixel = Color.FromArgb(RValue, GValue, BValue);
                    }
                    NewBitmap.SetPixel(x, y, MeanPixel);
                }
            }
            return NewBitmap;
        }
    }
}  
